import {
  createRouter,
  createWebHashHistory,
  createWebHistory,
  type NavigationGuardNext,
  type RouteLocationNormalized,
  type RouteMeta,
  type RouteRecordRaw,
} from 'vue-router'
import nprogress from '@/utils/nprogress'
import staticRouter from '@/routers/modules/staticRouter'
import useUserStores from '@/stores/modules/user'
import useAuthStores from '@/stores/modules/auth'
import { isPathMatch } from '@/utils/validate'
import { initDynamicRouter } from './modules/dynamicRouter'
import type { MenuMeta } from '@/types/router'

const whiteList = ['/login']
const isWhiteList = (path: string) => {
  return whiteList.some((pattern) => isPathMatch(pattern, path))
}

// 菜单
const menus = import.meta.glob('../views/**/menu.ts', {
  eager: true,
})

const menuMetaMap: Map<string, MenuMeta> = new Map(
  Object.entries(menus)
    .filter(([_, module]) => (module as { meta?: RouteMeta }).meta) // 过滤掉没有 meta 的模块
    .map(([path, module]) => {
      const formattedPath = path
        .replace('../views', '') // 去掉 '../views'
        .replace(/\/[^/]+\.ts$/, '') // 去掉最后的 '/**.vue'
      const meta = (module as { meta: RouteMeta }).meta
      return [formattedPath, meta]
    }),
)

// 页面组件
const components = import.meta.glob('../views/**/**.vue', {
  eager: true,
})

const asyncRouters: RouteRecordRaw[] = Object.entries(components)
  .filter(([_, module]) => (module as { meta?: RouteMeta }).meta) // 过滤掉没有 meta 的模块
  .map(([path, module]) => {
    const meta = (module as { meta: RouteMeta }).meta
    const component = (module as { default: any }).default
    component.name = meta.name

    // 去掉路径中的最后部分（/**.vue）
    const formattedPath = path
      .replace('../views', '') // 去掉 '../views'
      .replace(/\/[^/]+\.vue$/, '') // 去掉最后的 '/**.vue'

    return {
      path: formattedPath,
      name: meta.name,
      component,
      meta,
    }
  })

// 路由访问两种模式：带#号的哈希模式，正常路径的web模式。
type RouterMode = 'hash' | 'history'

const routerMode: Record<
  RouterMode,
  () => ReturnType<typeof createWebHashHistory> | ReturnType<typeof createWebHistory>
> = {
  hash: () => createWebHashHistory(),
  history: () => createWebHistory(),
}

const router = createRouter({
  history: routerMode['history'](),
  routes: [...staticRouter],
  strict: false,
  // 滚动行为
  scrollBehavior() {
    return {
      left: 0,
      top: 0,
    }
  },
})

/**
 * @description 前置路由
 */
router.beforeEach(
  async (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
    nprogress.start()

    // 2、标题切换，没有放置后置路由，是因为页面路径不存在，title会变成undefined
    document.title = (to.meta?.title as string) || import.meta.env.VITE_APP_TITLE

    const userStore = useUserStores()

    if (userStore.token) {
      // 已登录，访问登录页则重定向到首页
      if (to.path === '/login') {
        next({ path: '/' })
        return
      }

      // 白名单路径直接放行
      if (isWhiteList(to.path)) {
        next()
        return
      }

      // 如果用户信息不存在，获取用户信息并初始化动态路由
      if (!userStore.userInfo) {
        await userStore.getUserInfo()
        useAuthStores().setMenuMetaMap(menuMetaMap)
        await initDynamicRouter(asyncRouters)
        next({ ...to, replace: true })

        return
      }

      next()
    } else {
      // 未登录
      if (isWhiteList(to.path)) {
        // 在免登录白名单，直接进入
        next()
      } else {
        // 否则全部重定向到登录页
        next(`/login?redirect=${to.fullPath}`)
      }
    }
  },
)

/**
 * @description 重置路由
 */
export const resetRouter = () => {
  // TODO: 实现路由重置逻辑
}

/**
 * @description 路由跳转错误
 */
router.onError((error) => {
  // 结束全屏动画
  nprogress.done()
  console.warn('路由错误', error.message)
})

/**
 * @description 后置路由
 */
router.afterEach(() => {
  // 结束全屏动画
  nprogress.done()
})

export default router
